home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / tcl / tclx7_31.z / tclx7_31 / tcldev / tclX7.3a-p1 / tools / cpmanpages.tcl < prev    next >
Encoding:
Text File  |  1993-12-16  |  10.2 KB  |  325 lines

  1. #
  2. # cpmanpages.tcl -- 
  3. #
  4. # Tool used during build to copy manual pages to master directories.  This
  5. # program knows the internals of the build, so its very specific to this
  6. # task.
  7. #
  8. # It is run in the following manner:
  9. #
  10. #     cpmanpages ?flags? separator cmd func unix sourceDir targetDir
  11. #
  12. # flags are:
  13. #   o -rmcat - remove any existing "cat" files associated with man pages.
  14. #
  15. # arguments are:
  16. #   o separator - Either "." or "", the separator in the manual page directory
  17. #     name (/usr/man/man1 vs /usr/man/man.1).
  18. #   o cmd - Section to put the Tcl command manual pages in. (*.n pages).
  19. #   o func - Section to put the Tcl C function manual pages in. (*.3 pages).
  20. #   o unix - Section to put the Tcl Unix command manual pages in.
  21. #     Maybe empty. (*.1 pages).
  22. #   o sourceDir - directory containing manual pages to install.
  23. #   o targetDir - manual directory to install pages in.  This is the directory
  24. #     containing the section directories, e.g. /usr/local/man.
  25. #
  26. # If any of these strings are quoted with "@" (e.g. @.@), then the two "@"
  27. # are removed.  This is to work around problems with systems were quoted empty
  28. # strings don't make it past make and shell expansion, resulting in a missing
  29. # argument.
  30. #------------------------------------------------------------------------------
  31. # Copyright 1992-1993 Karl Lehenbauer and Mark Diekhans.
  32. #
  33. # Permission to use, copy, modify, and distribute this software and its
  34. # documentation for any purpose and without fee is hereby granted, provided
  35. # that the above copyright notice appear in all copies.  Karl Lehenbauer and
  36. # Mark Diekhans make no representations about the suitability of this
  37. # software for any purpose.  It is provided "as is" without express or
  38. # implied warranty.
  39. #------------------------------------------------------------------------------
  40. # $Id: cpmanpages.tcl,v 3.1 1993/12/16 15:35:43 markd Exp $
  41. #------------------------------------------------------------------------------
  42. #
  43.  
  44. #------------------------------------------------------------------------------
  45. # Unquote -- 
  46. #
  47. # Remove "@" if they quote a string.
  48. #------------------------------------------------------------------------------
  49.  
  50. proc Unquote str {
  51.     regsub -- {^@(.*)@$} $str {\1} str
  52.     return $str
  53. }
  54.  
  55. #------------------------------------------------------------------------------
  56. # CopyManFile -- 
  57. #
  58. # Called to open a copy a man file.  Recursively called to include .so files.
  59. #------------------------------------------------------------------------------
  60.  
  61. proc CopyManFile {sourceFile targetFH} {
  62.  
  63.     set sourceFH [open $sourceFile r]
  64.  
  65.     while {[gets $sourceFH line] >= 0} {
  66.         if [string match {.V[SE]*} $line] continue
  67.         if [string match {.so *} $line] {
  68.             set soFile [string trim [crange $line 3 end]]
  69.             CopyManFile "[file dirname $sourceFile]/$soFile" $targetFH
  70.             continue
  71.         }
  72.         puts $targetFH $line
  73.     }
  74.  
  75.     close $sourceFH
  76. }
  77.  
  78. #------------------------------------------------------------------------------
  79. # CopyManPage -- 
  80. #
  81. # Copy the specified manual page and change the ownership.  The manual page
  82. # is edited to remove change bars (.VS and .VE macros). Files included with .so
  83. # are merged in.
  84. #------------------------------------------------------------------------------
  85.  
  86. proc CopyManPage {sourceFile targetFile} {
  87.  
  88.     if ![file exists [file dirname $targetFile]] {
  89.         mkdir -path [file dirname $targetFile]
  90.     }
  91.     unlink -nocomplain $targetFile
  92.  
  93.     set targetFH [open $targetFile w]
  94.     CopyManFile $sourceFile $targetFH
  95.     close $targetFH
  96. }
  97.  
  98. #------------------------------------------------------------------------------
  99. # GetManNames --
  100. #
  101. #   Search a manual page (nroff source) for the name line.  Parse the name
  102. # line into all of the functions or commands that it references.  This isn't
  103. # comprehensive, but it works for all of the Tcl, TclX and Tk man pages.
  104. #
  105. # Parameters:
  106. #   o manFile (I) - The path to the  manual page file.
  107. # Returns:
  108. #   A list contain the functions or commands or {} if the name line can't be
  109. # found or parsed.
  110. #------------------------------------------------------------------------------
  111.  
  112. proc GetManNames manFile {
  113.  
  114.    set manFH [open $manFile]
  115.  
  116.    #
  117.    # Search for name line.  Once found, grab the next line that is not a
  118.    # nroff macro.  If we end up with a blank line, we didn't find it.
  119.    #
  120.    while {[gets $manFH line] >= 0} {
  121.        if [regexp {^.SH NAME.*$} $line] {
  122.            break
  123.        }
  124.    }
  125.    while {[gets $manFH line] >= 0} {
  126.        if {![string match ".*" $line]} break
  127.    }
  128.    close $manFH
  129.  
  130.    set line [string trim $line]
  131.    if {$line == ""} return
  132.  
  133.    #
  134.    # Lets try and parse the name list out of the line
  135.    #
  136.    if {![regexp {^(.*)(\\-)} $line {} namePart]} {
  137.        if {![regexp {^(.*)(-)} $line {} namePart]} return
  138.    }
  139.  
  140.    #
  141.    # This magic converts the name line into a list
  142.    #
  143.  
  144.    if {[catch {join [split $namePart ,] " "} namePart] != 0} return
  145.  
  146.    return $namePart
  147.  
  148. }
  149.  
  150. #------------------------------------------------------------------------------
  151. # InstallShortMan --
  152. #   Install a manual page on a system that does not have long file names.
  153. #
  154. # Parameters:
  155. #   o sourceFile - Manual page source file path.
  156. #   o targetDir - Directory to install the file in.
  157. #   o extension - Extension to use for the installed file.
  158. # Returns:
  159. #   A list of the man files created, relative to targetDir.
  160. #------------------------------------------------------------------------------
  161.  
  162. proc InstallShortMan {sourceFile targetDir extension} {
  163.  
  164.     set manFileName "[file tail [file root $sourceFile]].$extension"
  165.  
  166.     CopyManPage $sourceFile "$targetDir/$manFileName"
  167.  
  168.     return $manFileName
  169. }
  170.  
  171. #------------------------------------------------------------------------------
  172. # InstallLongMan --
  173. #   Install a manual page on a system that has long file names.
  174. #
  175. # Parameters:
  176. #   o sourceFile - Manual page source file path.
  177. #   o targetDir - Directory to install the file in.
  178. #   o extension - Extension to use for the installed file.
  179. # Returns:
  180. #   A list of the man files created, relative to targetDir.  They are all links
  181. # to the same entry.
  182. #------------------------------------------------------------------------------
  183.  
  184. proc InstallLongMan {sourceFile targetDir extension} {
  185.  
  186.     set manNames [GetManNames $sourceFile]
  187.     if [lempty $manNames] {
  188.         set baseName [file tail [file root $sourceFile]]
  189.         puts stderr "Warning: can't parse NAME line for man page: $sourceFile."
  190.         puts stderr "         Manual page only available as: $baseName"
  191.         set manNames [list [file tail [file root $sourceFile]]]
  192.     }
  193.  
  194.     # Copy file to the first name in the list.
  195.  
  196.     set firstFilePath $targetDir/[lvarpop manNames].$extension
  197.     set created [list [file tail $firstFilePath]]
  198.  
  199.     CopyManPage $sourceFile $firstFilePath
  200.  
  201.     # Link it to the rest of the names in the list.
  202.  
  203.     foreach manName $manNames {
  204.         set targetFile  $targetDir/$manName.$extension
  205.         unlink -nocomplain $targetFile
  206.         if {[catch {
  207.                 link $firstFilePath $targetFile
  208.             } msg] != 0} {
  209.             puts stderr "error from: link $firstFilePath $targetFile"
  210.             puts stderr "    $msg"
  211.         } else {
  212.             lappend created [file tail $targetFile]
  213.         }
  214.     }
  215.     return $created
  216. }
  217.  
  218. #------------------------------------------------------------------------------
  219. # InstallManPage --
  220. #   Install a manual page on a system.
  221. #
  222. # Parameters:
  223. #   o sourceFile - Manual page source file path.
  224. #   o manDir - Directory to build the directoy containing the manual files in.
  225. #   o section - Section to install the manual page in.
  226. # Globals
  227. #   o longNames - If long file names are supported.
  228. #   o manSeparator - Character used to seperate man directory name from the
  229. #     section name.
  230. #   o rmcat - true if cat files are to be removed.
  231. #------------------------------------------------------------------------------
  232.  
  233. proc InstallManPage {sourceFile manDir section} {
  234.     global longNames manSeparator rmcat
  235.  
  236.     set targetDir "$manDir/man${manSeparator}${section}"
  237.  
  238.     if $longNames {
  239.         set files [InstallLongMan $sourceFile $targetDir $section]
  240.     } else {
  241.         set files [InstallShortMan $sourceFile $targetDir $section]
  242.     }
  243.    
  244.     if $rmcat {
  245.         foreach file $files {
  246.             unlink -nocomplain \
  247.                 [list $manDir/cat${manSeparator}${section}/$file]
  248.         }
  249.     }
  250. }
  251.  
  252. #------------------------------------------------------------------------------
  253. # main prorgam
  254.  
  255. if {[llength $argv] < 6 || [llength $argv] > 7} {
  256.     puts stderr "wrong # args: cpmanpages ?flags? separator cmd func unix sourceDir targetDir"
  257.     exit 1
  258. }
  259.  
  260. umask 022
  261.  
  262. # Parse command line args
  263.  
  264. set rmcat 0
  265. if {[lindex $argv 0] == "-rmcat"} {
  266.     set rmcat 1
  267.     lvarpop argv
  268. }
  269.  
  270. set manSeparator    [Unquote [lindex $argv 0]]
  271. set sectionXRef(.n) [Unquote [lindex $argv 1]]
  272. set sectionXRef(.3) [Unquote [lindex $argv 2]]
  273. set sectionXRef(.1) [Unquote [lindex $argv 3]]
  274. set sourceDir       [Unquote [lindex $argv 4]]
  275. set targetDir       [Unquote [lindex $argv 5]]
  276.  
  277. # Remove undefined sections from the array.
  278.  
  279. foreach sec [array names sectionXRef] {
  280.    if [lempty sectionXRef($sec)] {
  281.        unset sectionXRef($sec)
  282.    }
  283. }
  284.  
  285. puts stdout "Copying manual pages from $sourceDir to $targetDir"
  286.  
  287. # Determine if long file names are available.
  288.  
  289. if ![file exists $targetDir] {
  290.     mkdir -path $targetDir
  291. }
  292. set testName "$targetDir/TclX-long-test-file-name"
  293.  
  294. if [catch {open $testName w} fh] {
  295.     puts stdout ""
  296.     puts stdout "*** NOTE: long file names do not appear to be available on"
  297.     puts stdout "*** this system. Attempt to create a long named file in
  298.     puts stdout "*** $targetDir returned the error: $errorCode"
  299.     puts stdout ""
  300.     set longNames 0
  301. } else {
  302.     close $fh
  303.     unlink $testName
  304.     set longNames 1
  305. }
  306.  
  307. set sourceFiles [glob -nocomplain -- $sourceDir/*.man $sourceDir/*.n \
  308.                       $sourceDir/*.1 $sourceDir/*.3]
  309.  
  310. set ignoreFiles {tclsh.1}
  311.  
  312. # Actually install the files.
  313.  
  314. foreach sourceFile $sourceFiles {
  315.     if {[lsearch $ignoreFiles [file tail $sourceFile]] >= 0} continue
  316.  
  317.     set ext [file extension $sourceFile]
  318.     if ![info exists sectionXRef($ext)] {
  319.         puts stderr "WARNING: Don't know how to handle section for $sourceFile,"
  320.         continue
  321.     }
  322.     InstallManPage $sourceFile $targetDir $sectionXRef($ext)
  323. }
  324.  
  325.